﻿using AuthExtensions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using static MultiTenant.FreeSql.AuthExtensions;

namespace MultiTenant.FreeSql;

public class CustomJwtBearerHandler : JwtBearerHandler
{

    private readonly AuthConfig _authConfig;
    public CustomJwtBearerHandler(IOptions<AuthConfig> authconfig,
        IOptionsMonitor<JwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder)
      : base(options, logger, encoder)
    {
        _authConfig = authconfig.Value;
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        
         
      
        // 从请求头中获取Authorization header
        if (!Request.Headers.TryGetValue("Authorization", out var authorizationHeader) || !authorizationHeader.ToString().StartsWith("Bearer "))
        {
            if (_authConfig.QueryToken)
            {
                var accessToken = Request.Query["access_token"];
               // Request.HttpContext = accessToken;
            }
            return AuthenticateResult.Fail("No JWT token found in the request.");
        }

        var token = "";
        // 验证JWT token
        try
        {
            if (TenantContext.Tenant != null && TenantContext.Tenant.Id > 0)
            {
                var validationParameters = Options.TokenValidationParameters.Clone();
                var tokenHandler = new JwtSecurityTokenHandler();

                // 自定义的验证逻辑
                if (Options.TokenValidationParameters.ValidateIssuerSigningKey)
                {
                    validationParameters.IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TenantContext.Tenant.Jwt.Secret));
                }

                if (Options.TokenValidationParameters.ValidateIssuer)
                {
                    validationParameters.ValidIssuer = TenantContext.Tenant.Jwt.Issuer;
                }

                if (Options.TokenValidationParameters.ValidateAudience)
                {
                    validationParameters.ValidAudience = TenantContext.Tenant.Jwt.Audience;
                }
                string authorization = Request.Headers["Authorization"].ToString() ?? "";
                if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
                {
                    token = authorization.Substring(7).Trim();
                }
                var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
                var ticket = new AuthenticationTicket(principal, Scheme.Name);
                return AuthenticateResult.Success(ticket);
            }
            else
            {

                var validationParameters = Options.TokenValidationParameters.Clone();
                var tokenHandler = new JwtSecurityTokenHandler();

                // 自定义的验证逻辑
                if (Options.TokenValidationParameters.ValidateIssuerSigningKey)
                {
                    validationParameters.IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_authConfig.SigningKey));
                }

                if (Options.TokenValidationParameters.ValidateIssuer)
                {
                    validationParameters.ValidIssuer = _authConfig.ValidIssuer;
                }

                if (Options.TokenValidationParameters.ValidateAudience)
                {
                    validationParameters.ValidAudience = _authConfig.ValidAudience;
                }
                string authorization = Request.Headers["Authorization"].ToString()??"";
                if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
                {
                    token = authorization.Substring(7).Trim();
                }
                var principal = tokenHandler.ValidateToken(token, validationParameters, out var validatedToken);
                var ticket = new AuthenticationTicket(principal, Scheme.Name);
                return AuthenticateResult.Success(ticket);
            }

        }
        catch (Exception ex)
        {
            // 验证失败，记录异常并返回Fail结果
            Logger.LogError(ex, "JWT token validation failed.");
            return AuthenticateResult.Fail("JWT token validation failed.");
        }
    }

 
}
